/**
 * Created by FreezeSoul on 2016/5/30.
 */
define([
    "app/core/base",
    "app/core/util",
    "../echartsMeta",
    "jquery",
    "underscore",
    'JSONParse',
    'loglevel',
    "echarts"
], function (Chart, Util, Meta, $, _, JSON, log, ec) {

    var property = {
        config: "property",
        option: []
            .concat($.extend(true, [], Meta.titleProperties))
            .concat($.extend(true, [], Meta.legendProperties))
            .concat($.extend(true, [], Meta.tooltipProperties))
            .concat($.extend(true, [], Meta.toolboxProperties))
            .concat([
                {
                    group: '其他',
                    id: 'b757a938-727f-4026-9d96-22c86e4ccb18',
                    name: '背景色',
                    enable: false,
                    type: 'color',
                    value: 'transparent',
                    default: 'transparent',
                    link: 'backgroundColor',
                    tooltip: '背景色，如需透明请填写:transparent'
                },
                {
                    group: '其他',
                    id: '9b9ed398-612a-454e-82a4-38ea5478c973',
                    name: '序列颜色',
                    enable: false,
                    type: 'colors',
                    value: [],
                    default: [],
                    data: [
                        '#FE8463', '#9BCA63', '#FAD860', '#60C0DD', '#0084C6',
                        '#D7504B', '#C6E579', '#26C0C0', '#F0805A', '#F4E001',
                        '#B5C334'
                    ],
                    link: 'color',
                    tooltip: '序列颜色会根据给出的颜色集合依次渲染'
                },
                {
                    group: '其他',
                    id: '252c8502-3aae-41d8-8cd1-712818495059',
                    name: 'X轴类型',
                    enable: false,
                    type: 'select',
                    value: 'category',
                    default: 'category',
                    data: [{
                        value: 'category',
                        text: '类目轴'
                    }, {
                        value: 'value',
                        text: '数值轴'
                    }, {
                        value: 'time',
                        text: '时间轴'
                    }],
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.xAxis)) {
                            _.each(option.xAxis, function (xAxis) {
                                Util.setOption("type", _this.value, xAxis);
                            });
                        } else {
                            Util.setOption("type", _this.value, option.xAxis);
                        }
                    },
                    tooltip: 'X坐标轴类型: <br/> 数值轴，适用于连续数据。<br/>类目轴，适用于离散的类目数据，为该类型时必须通过 data 设置类目数据。<br/>时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，<br/>在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，<br/>星期，日还是小时范围的刻度。'
                },
                {
                    group: '其他',
                    id: '0b774e0b-28c4-4e71-a022-938c68ef9c63',
                    name: 'Y轴类型',
                    enable: false,
                    type: 'select',
                    value: 'value',
                    default: 'value',
                    data: [{
                        value: 'category',
                        text: '类目轴'
                    }, {
                        value: 'value',
                        text: '数值轴'
                    }, {
                        value: 'time',
                        text: '时间轴'
                    }],
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.yAxis)) {
                            _.each(option.yAxis, function (yAxis) {
                                Util.setOption("type", _this.value, yAxis);
                            });
                        } else {
                            Util.setOption("type", _this.value, option.yAxis);
                        }
                    },
                    tooltip: 'Y坐标轴类型: <br/> 数值轴，适用于连续数据。<br/>类目轴，适用于离散的类目数据，为该类型时必须通过 data 设置类目数据。<br/>时间轴，适用于连续的时序数据，与数值轴相比时间轴带有时间的格式化，<br/>在刻度计算上也有所不同，例如会根据跨度的范围来决定使用月，<br/>星期，日还是小时范围的刻度。'
                },
                {
                    group: '其他',
                    id: 'fa99c7f5-1e78-4143-9e5f-b3bd3827cca0',
                    name: 'X轴颜色',
                    enable: false,
                    type: 'color',
                    value: '#333333',
                    default: '#333333',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.xAxis)) {
                            _.each(option.xAxis, function (xAxis) {
                                Util.setOption("axisLine.lineStyle.color", _this.value, xAxis);
                                Util.setOption("axisTick.lineStyle.color", _this.value, xAxis);
                                Util.setOption("axisLabel.textStyle.color", _this.value, xAxis);
                            });
                        } else {
                            Util.setOption("axisLine.lineStyle.color", _this.value, option.xAxis);
                            Util.setOption("axisTick.lineStyle.color", _this.value, option.xAxis);
                            Util.setOption("axisLabel.textStyle.color", _this.value, option.xAxis);
                        }
                    },
                    tooltip: 'X坐标轴轴线、刻度、字体的颜色'
                },
                {
                    group: '其他',
                    id: '1dfdf36a-c120-4b1c-b6ed-d6009eeaa1d0',
                    name: 'Y轴颜色',
                    enable: false,
                    type: 'color',
                    value: '#333333',
                    default: '#333333',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.yAxis)) {
                            _.each(option.yAxis, function (yAxis) {
                                Util.setOption("axisLine.lineStyle.color", _this.value, yAxis);
                                Util.setOption("axisTick.lineStyle.color", _this.value, yAxis);
                                Util.setOption("axisLabel.textStyle.color", _this.value, yAxis);
                            });
                        } else {
                            Util.setOption("axisLine.lineStyle.color", _this.value, option.yAxis);
                            Util.setOption("axisTick.lineStyle.color", _this.value, option.yAxis);
                            Util.setOption("axisLabel.textStyle.color", _this.value, option.yAxis);
                        }
                    },
                    tooltip: 'Y坐标轴轴线、刻度、字体的颜色'
                },
                {
                    group: '其他',
                    id: 'cb259bb6-dfb2-46a1-8b1e-b6893d631c57',
                    name: 'X轴分割线',
                    enable: false,
                    type: 'checked',
                    value: true,
                    default: true,
                    tooltip: '是否显示X轴分割线',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.xAxis)) {
                            _.each(option.xAxis, function (xAxis) {
                                Util.setOption("splitLine.show", _this.value, xAxis);
                            });
                        } else {
                            Util.setOption("splitLine.show", _this.value, xAxis);
                        }
                    }
                },
                {
                    group: '其他',
                    id: 'c879c3a7-c1ad-4058-8745-055aad9d137c',
                    name: 'Y轴分割线',
                    enable: false,
                    type: 'checked',
                    value: true,
                    default: true,
                    tooltip: '是否显示Y轴分割线',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if ($.isArray(option.yAxis)) {
                            _.each(option.yAxis, function (yAxis) {
                                Util.setOption("splitLine.show", _this.value, yAxis);
                            });
                        } else {
                            Util.setOption("splitLine.show", _this.value, yAxis);
                        }
                    }
                }
            ])
            .concat([
                {
                    group: '其他',
                    id: '52aa59aa-3689-4959-a6f9-97783eeacb4e',
                    name: '图形最小值',
                    enable: false,
                    type: 'number',
                    value: 0,
                    default: 0,
                    tooltip: '视觉映射组件,图形大小最小值',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if (option.visualMap && $.isArray(option.visualMap) && option.visualMap.length > 0) {
                            $.each(option.visualMap, function (i, v) {
                                if (v.inRange && v.inRange.symbolSize
                                    && v.outOfRange && v.outOfRange.symbolSize) {
                                    v.inRange.symbolSize[0] = _this.value;
                                    v.outOfRange.symbolSize[0] = _this.value;
                                }
                            })
                        }
                    }
                },
                {
                    group: '其他',
                    id: '5f9fddbc-1100-4ae3-ad90-90b30f3781ce',
                    name: '图形最大值',
                    enable: false,
                    type: 'number',
                    value: 75,
                    default: 75,
                    tooltip: '视觉映射组件,图形大小最大值',
                    link: function (option) {
                        var _this = this;
                        if (_this.enable === false) return;
                        if (option.visualMap && $.isArray(option.visualMap) && option.visualMap.length > 0) {
                            $.each(option.visualMap, function (i, v) {
                                if (v.inRange && v.inRange.symbolSize
                                    && v.outOfRange && v.outOfRange.symbolSize) {
                                    v.inRange.symbolSize[1] = _this.value;
                                    v.outOfRange.symbolSize[1] = _this.value;
                                }
                            })
                        }
                    }
                },
                {
                    group: '其他',
                    id: 'e6588782-1dbe-448a-b9ad-c81cad90b1c5',
                    name: '提示格式化',
                    enable: false,
                    type: 'textarea',
                    value: '' +
                        'function (obj) {\n' +
                        '   var value = obj.value;\n' +
                        '   return "X轴数值："+ value[0]+"<br/>Y轴数值："+ value[1]+"<br/>图形数值："+ value[2];\n' +
                        '}\n',
                    default: '' +
                        'function (obj) {\n' +
                        '   var value = obj.value;\n' +
                        '   return "X轴数值："+ value[0]+"<br/>Y轴数值："+ value[1]+"<br/>图形数值："+ value[2];\n' +
                        '}\n',
                    link: function (option) {
                        if (option.tooltip) {
                            option.tooltip.formatter = eval('(' + this.value + ')');
                        }
                    },
                    tooltip: '提示信息格式化函数<br/>回调函数格式：<br/> (params: Object|Array, ticket: string, callback: (ticket: string, html: string)) => string<br/>第一个参数 params 是 formatter 需要的数据集。格式如下：<br/><pre>{<br/>     componentType: "series",<br/>     // 系列类型<br/>     seriesType: string,<br/>     // 系列在传入的 option.series 中的 index<br/>     seriesIndex: number,<br/>     // 系列名称<br/>     seriesName: string,<br/>     // 数据名，类目名<br/>     name: string,<br/>     // 数据在传入的 data 数组中的 index<br/>     dataIndex: number,<br/>     // 传入的原始数据项<br/>     data: Object,<br/>     // 传入的数据值<br/>     value: number|Array,<br/>     // 数据图形的颜色<br/>     color: string,<br/>     // 饼图的百分比<br/>     percent: number,<br/> }</pre>在 trigger 为 "axis" 的时候 params 是多个系列的数据数组。'
                }
            ])
            .concat([
                {
                    group: '序列',
                    id: 'f53a0a43-6d1b-43e0-b514-122a8b155ece',
                    name: '序列',
                    type: 'group',
                    items: [],
                    option: [
                        {
                            id: '8d613598-8e08-49ce-908e-7524c305910f',
                            name: '序列名称',
                            enable: true,
                            type: 'text',
                            value: '',
                            default: '',
                            link: 'name',
                            tooltip: '序列名称，用于legend'
                        },
                        {
                            id: 'a320684c-8ca5-49f0-aab7-853e0fde9e5c',
                            name: '过滤列名称',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            tooltip: '绑定数据集，客户端过滤字段列名称'
                        },
                        {
                            id: '96f30ae6-6fe0-4faa-8b7f-a302a49a0434',
                            name: '过滤列默认值',
                            enable: false,
                            type: 'text',
                            value: '',
                            default: '',
                            tooltip: '绑定数据集，客户端过滤字段默认值'
                        },
                        {
                            id: '17994381-e1fe-4551-a852-a5a0571ed899',
                            name: '绑定设置',
                            enable: true,
                            type: 'sortBinding',
                            dataset: '',
                            columns: [],
                            tooltip: '序列绑定设置，与数据集关系'
                        }
                    ],
                    link: 'series',
                    tooltip: '字段说明:<br/>分组控件，支持动态扩展，内部可增加支持的类型属性'
                }
            ]).concat($.extend(true, [], Meta.otherProperties)),
        //需要针对组件映射属性至组件Option
        MapOption: function (option) {
            Util.linkOption(this.option, option);
        }
    };

    var bar = Chart.extend({
        constructor: function (layout) {
            this._layout = layout;
            this._container = null;
            this._lastdata = null;
            this._chart = null;
            this._option = {
                Binding: [],
                Events: [],
                Extend: $.extend(true, {}, property),
                Option: {
                    legend: {
                        y: 'top',
                        data: ['北京', '上海', '广州']
                    },
                    tooltip: {
                        padding: 10
                    },
                    xAxis: {
                        type: 'value',
                        name: '日期'
                    },
                    yAxis: {
                        type: 'value',
                        name: 'AQI指数'
                    },
                    visualMap: [
                        {
                            show: false,
                            dimension: 2,
                            min: 0,
                            max: 250,
                            inRange: {
                                symbolSize: [10, 100]
                            },
                            outOfRange: {
                                symbolSize: [10, 100],
                                color: ['rgba(255,255,255,.2)']
                            }
                        }
                    ],
                    series: [
                        {
                            name: '北京',
                            type: 'scatter',
                            itemStyle: {
                                normal: {
                                    opacity: 0.8,
                                    shadowBlur: 10,
                                    shadowOffsetX: 0,
                                    shadowOffsetY: 0,
                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                                }
                            },
                            data: [[1, 55, 9], [2, 25, 11], [3, 56, 7], [4, 33, 7], [5, 42, 24], [6, 82, 58], [7, 74, 49], [8, 78, 55], [9, 267, 216], [10, 185, 127], [11, 39, 19], [12, 41, 11], [13, 64, 38], [14, 108, 79], [15, 108, 63], [16, 33, 6], [17, 94, 66], [18, 186, 142], [19, 57, 31], [20, 22, 8], [21, 39, 15], [22, 94, 69], [23, 99, 73], [24, 31, 12], [25, 42, 27], [26, 154, 117], [27, 234, 185], [28, 160, 120], [29, 134, 96], [30, 52, 24]]
                        },
                        {
                            name: '上海',
                            type: 'scatter',
                            itemStyle: {
                                normal: {
                                    opacity: 0.8,
                                    shadowBlur: 10,
                                    shadowOffsetX: 0,
                                    shadowOffsetY: 0,
                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                                }
                            },
                            data: [[1, 26, 37], [2, 85, 62], [3, 78, 38], [4, 21, 21], [5, 41, 42], [6, 56, 52], [7, 64, 30], [8, 55, 48], [9, 76, 85], [10, 91, 81], [11, 84, 39], [12, 64, 51], [13, 70, 69], [14, 77, 105], [15, 109, 68], [16, 73, 68], [17, 54, 27], [18, 51, 61], [19, 91, 71], [20, 73, 102], [21, 73, 50], [22, 84, 94], [23, 93, 77], [24, 99, 130], [25, 146, 84], [26, 113, 108], [27, 81, 48], [28, 56, 48], [29, 82, 92], [30, 106, 116]]
                        },
                        {
                            name: '广州',
                            type: 'scatter',
                            itemStyle: {
                                normal: {
                                    opacity: 0.8,
                                    shadowBlur: 10,
                                    shadowOffsetX: 0,
                                    shadowOffsetY: 0,
                                    shadowColor: 'rgba(0, 0, 0, 0.5)'
                                }
                            },
                            data: [[1, 91, 45], [2, 65, 27], [3, 83, 60], [4, 109, 81], [5, 106, 77], [6, 109, 81], [7, 106, 77], [8, 89, 65], [9, 53, 33], [10, 80, 55], [11, 117, 81], [12, 99, 71], [13, 95, 69], [14, 116, 87], [15, 108, 80], [16, 134, 83], [17, 79, 43], [18, 71, 46], [19, 97, 71], [20, 84, 57], [21, 87, 63], [22, 104, 77], [23, 87, 62], [24, 168, 128], [25, 65, 45], [26, 39, 24], [27, 39, 24], [28, 93, 68], [29, 188, 143], [30, 174, 131]]
                        }
                    ]
                }
            };
        },
        init: function (element) {
            try {
                this._container = element;
                this._chart = ec.init(element, null, {
                    renderer: 'canvas'
                });
                this._bindEvent();
            } catch (e) {
                log.error(e);
            }
        },
        //TODO:需要重写的部分
        _bindEvent: function () {
            var _this = this;
            if (!this._filterDataHandle) {
                this._filterDataHandle = function (params) {
                    _this.filterDataHandle.call(_this, params);
                };
            }
            this._layout.removeListener("filterData", this._filterDataHandle);
            this._layout.addListener("filterData", this._filterDataHandle);
        },
        filterDataHandle: function (params) {
            var _this = this;
            var flag = false;
            var seriesItems = _.findWhere(_this._option.Extend.option, {type: 'group'});
            $.each(seriesItems.items, function (i, item) {
                var filterColumn = _.findWhere(item.option, {name: '过滤列名称'});
                var filterValue = _.findWhere(item.option, {name: '过滤列默认值'});

                if (filterColumn && filterValue
                    && filterColumn.enable && filterValue.enable
                    && filterColumn.value !== "" && filterValue.value !== ""
                ) {
                    for (var prop in params) {
                        if (!params.hasOwnProperty(prop)) continue;
                        if (filterColumn.value === prop) {
                            filterValue.value = params[prop];
                            flag = true;
                        }
                    }
                }
            });
            if (flag && _this._lastdata) {
                _this.setData(_this._lastdata);
            }
        },
        example: function () {
            try {
                this._chart.setOption(this._option.Option, true);
            } catch (e) {
                log.error(e);
            }
        },
        _readProperty: function () {
            try {
                if (!this._option.Extend) return;
                Util.deepMapOption(property, this._option.Extend, this._option.Option);
            } catch (e) {
                log.error(e);
            }
        },
        //TODO:需要重写的部分
        _bindData: function (data) {
            var tables = data;
            var _this = this;

            //根据每个option自行查找，可通过id或name，这里因为只有一个group,因此通过type查找
            var seriesItems = _.findWhere(this._option.Extend.option, {type: 'group'});

            if (!$.isArray(this._option.Option.xAxis))
                this._option.Option.xAxis = [this._option.Option.xAxis];

            if (!$.isArray(this._option.Option.yAxis))
                this._option.Option.yAxis = [this._option.Option.yAxis];

            //清除工作
            if (seriesItems.items.length > 0) {
                this._option.Option.legend.data = [];
                $.each(this._option.Option.xAxis, function (i, xAxis) {
                    if (xAxis.type === "category") {
                        xAxis.data = [];
                    } else {
                        delete xAxis.data;
                    }
                });
                $.each(this._option.Option.yAxis, function (i, yAxis) {
                    if (yAxis.type === "category") {
                        yAxis.data = [];
                    } else {
                        delete yAxis.data;
                    }
                });
            }


            var categoryAxis = undefined;
            if (this._option.Option.xAxis[0].type === "category") {
                categoryAxis = this._option.Option.xAxis[0];
            }
            if (this._option.Option.yAxis[0].type === "category") {
                categoryAxis = this._option.Option.yAxis[0];
            }


            //绑定数据
            $.each(seriesItems.items, function (i, item) {
                var bindProperty = _.findWhere(item.option, {type: 'sortBinding'});
                if (!bindProperty) return;

                var dataSetCode = bindProperty.dataset;
                var columns = bindProperty.columns;

                var nameProperty = _.findWhere(item.option, {name: '序列名称'});
                if (nameProperty) {
                    _this._option.Option.legend.data.push(nameProperty.value);
                }

                if (dataSetCode && columns && $.isArray(columns) && columns.length >= 3) {
                    var table = tables[dataSetCode];
                    var data = [];
                    table = _this._filterTable(item.option, table);
                    $.each(table, function (j, row) {
                        if (categoryAxis && categoryAxis.data.indexOf(row[columns[0].ColumnName]) === -1) {
                            categoryAxis.data.push(row[columns[0].ColumnName]);
                        }
                        var dataArray = [];
                        $.each(columns, function (i, column) {
                            dataArray.push(row[column.ColumnName])
                        });
                        data.push(dataArray);
                    });

                    if (_this._option.Option.series.length >= i + 1) {
                        _this._option.Option.series[i].data = data;
                    }
                }
            });
        },
        _filterTable: function (option, table) {
            var filterColumn = _.findWhere(option, {name: '过滤列名称'});
            var filterValue = _.findWhere(option, {name: '过滤列默认值'});

            if (filterColumn && filterValue
                && filterColumn.enable && filterValue.enable
                && filterColumn.value !== "" && filterValue.value !== ""
            ) {
                var tableCopy = _.map(table, _.clone);
                return _.filter(tableCopy, function (row) {
                    return row[filterColumn.value] === filterValue.value;
                });
            }
            return table;
        },
        setData: function (data) {
            try {
                this._lastdata = data;
                this._readProperty();

                if (data
                    && this._option.Binding
                    && this._option.Binding.length > 0
                    && this._option.Extend) {

                    this._bindData(data);

                    this._readProperty();
                }
                this._chart.setOption(this._option.Option, true);

                //Util.setEChartsMeta(this, this._container, this._option.Extend.option);
            } catch (e) {
                log.error(e);
            }
        },
        setOption: function (option) {
            try {
                return this._option = $.extend(true, {}, option);
            } catch (e) {
                log.error(e);
            }
        },
        getOption: function () {
            try {
                this._readProperty();
            } catch (e) {
                log.error(e);
            }
            return this._option;
        },
        setTheme: function (theme) {
            try {
                this._chart.setTheme(theme);
            } catch (e) {
                log.error(e);
            }
        },
        resize: function () {
            try {
                this._chart.resize();
            } catch (e) {
                log.error(e);
            }
        },
        showLoading: function () {
            try {
                if (this._layout && this._layout.showLoading) {
                    this._layout.showLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        hideLoading: function () {
            try {
                if (this._layout && this._layout.hideLoading) {
                    this._layout.hideLoading(this);
                }
            } catch (e) {
                log.error(e);
            }
        },
        dispose: function () {
            try {
                this._chart.dispose();
                this._layout.removeListener("filterData", this._filterDataHandle);
            } catch (e) {
                log.error(e);
            }
        }, getElement: function () {
            return this._container;
        },
        getChart: function () {
            return this._chart;
        }
    });

    return {
        Chart: bar,
        Property: property
    };
});